/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-06-19     N0953692       the first version
 */
#include <rtthread.h>
#include <rtdevice.h>
#include <lcd_st7735s.h>
//#include <bsp.h>
#include <bsp_key.h>

#define INA226_I2C_BUS    "i2c1"      // I2C总线名称

#define INA226_ADDR1        0x40       // I2C设备地址(A0=A1=GND)
#define INA226_ADDR2        0x45       // I2C设备地址(A0=A1=VS)

#define INA226_REG_CONFIG  0x00       // 配置寄存器地址
#define INA226_REG_CAL     0x05       // 校准寄存器地址
#define INA226_REG_CURRENT 0x04       // 电流寄存器地址
#define INA226_REG_SV      0X01        //分流电压
#define INA226_REG_BUS     0X02        //总线电压
#define INA226_REG_PWR     0X03        //电源功率



// INA226配置参数
#define INA226_AVG        0x01 << 9    // 1次平均
#define INA226_VBUS_CT    0x4 << 6    // VBUS转换时间1.1ms
#define INA226_VSH_CT      0x4 << 3   // VSH转换时间1.1ms
#define INA226_MODE        0x7        // 连续测量分流和总线电压
#define INA226_CONFIG      (INA226_AVG | INA226_VBUS_CT | INA226_VSH_CT | INA226_MODE)
//#define INA226_CONFIG      0x4127     //标准配置

// 分流电阻值 (0.01Ω)
#define R_SHUNT           2.0f
// 最大预期电流 (8.192A)
#define MAX_CURRENT       0.04096f
#define Voltage_LSB     1.25f   //总线电压 LSB 1.25mV

static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
static float current_lsb;             // 电流分辨率

//static float voltageVal  ;
//static float Shunt_voltage ;
//static float Shunt_Current  ;
//static float Power ;
//
//static float voltageValB  ;
//static float Shunt_voltageB  ;
//static float Shunt_CurrentB  ;
//static float PowerB  ;


/* 向INA226写入寄存器 */
static rt_err_t ina226_write_reg(rt_uint8_t addr,rt_uint8_t reg, rt_uint16_t value)
{
    rt_uint8_t buf[3];
    struct rt_i2c_msg msgs;

    buf[0] = reg;
    buf[1] = value >> 8;   // 高字节
    buf[2] = value & 0xFF; // 低字节

    msgs.addr  = addr;
    msgs.flags = RT_I2C_WR;
    msgs.buf   = buf;
    msgs.len   = 3;

    if (rt_i2c_transfer(i2c_bus, &msgs, 1) == 1) {
        return RT_EOK;
    }
    return -RT_ERROR;
}

/* 从INA226读取寄存器 */
static rt_err_t ina226_read_reg(rt_uint8_t addr,rt_uint8_t reg, rt_uint16_t *value)
{
    rt_uint8_t buf[2];
    struct rt_i2c_msg msgs[2];

    /* 发送寄存器地址 */
    msgs[0].addr  = addr;
    msgs[0].flags = RT_I2C_WR;
    msgs[0].buf   = &reg;
    msgs[0].len   = 1;

    /* 读取数据 */
    msgs[1].addr  = addr;
    msgs[1].flags = RT_I2C_RD;
    msgs[1].buf   = buf;
    msgs[1].len   = 2;

    if (rt_i2c_transfer(i2c_bus, msgs, 2) == 2) {
        *value = (buf[0] << 8) | buf[1];
        return RT_EOK;
    }
    return -RT_ERROR;
}

/* 初始化INA226 */
static rt_err_t ina226_init(void)
{
    rt_uint16_t val;

    // 查找I2C2总线
    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(INA226_I2C_BUS);
    if (i2c_bus == RT_NULL) {
        rt_kprintf("I2C bus %s not found!\n", INA226_I2C_BUS);
        return -RT_ERROR;
    }

    // 计算电流分辨率 (LSB)
    current_lsb = MAX_CURRENT / 32768.0f;  // 8.192A / 32768 = 30.5175μA/LSB

    // 计算校准值 (公式: Cal = 0.00512 / (current_lsb * R_SHUNT))
    float cal_val_float = 0.00512f / (current_lsb * R_SHUNT);
    rt_uint16_t cal_val = (rt_uint16_t)cal_val_float;

    // 写入配置寄存器
     if (ina226_write_reg(INA226_ADDR1,INA226_REG_CONFIG, 0x8000) != RT_EOK) {
         rt_kprintf("Configure INA226_1 failed!\n");
         return -RT_ERROR;
     }


    // 写入配置寄存器
     if (ina226_write_reg(INA226_ADDR1,INA226_REG_CONFIG, INA226_CONFIG) != RT_EOK) {
         rt_kprintf("Configure INA226_2 failed!\n");
         return -RT_ERROR;
     }

    // 写入校准寄存器
    if (ina226_write_reg(INA226_ADDR1,INA226_REG_CAL, cal_val) != RT_EOK) {
        rt_kprintf("Calibrate INA226 failed!\n");
        return -RT_ERROR;
    }



    // 验证配置
    if (ina226_read_reg(INA226_ADDR1,INA226_REG_CONFIG, &val) == RT_EOK) {
        rt_kprintf("INA226 Config Register: 0x%04X\n", val);
    }

    rt_kprintf("INA226 Calibration: 0x%04X (%.1f)\n", cal_val, cal_val_float);
    rt_kprintf("Current LSB: %d.%06d mA per bit\n", (int)current_lsb,(int)(current_lsb-(int)current_lsb)*10000000);

    // 写入配置寄存器
     if (ina226_write_reg(INA226_ADDR2,INA226_REG_CONFIG, 0x8000) != RT_EOK) {
         rt_kprintf("Configure INA2262_1 failed!\n");
         return -RT_ERROR;
     }


    // 写入配置寄存器
     if (ina226_write_reg(INA226_ADDR2,INA226_REG_CONFIG, INA226_CONFIG) != RT_EOK) {
         rt_kprintf("Configure INA2262_2 failed!\n");
         return -RT_ERROR;
     }

    // 写入校准寄存器
    if (ina226_write_reg(INA226_ADDR2,INA226_REG_CAL, cal_val) != RT_EOK) {
        rt_kprintf("Calibrate INA2262 failed!\n");
        return -RT_ERROR;
    }



    // 验证配置
    if (ina226_read_reg(INA226_ADDR2,INA226_REG_CONFIG, &val) == RT_EOK) {
        rt_kprintf("INA2262 Config Register: 0x%04X\n", val);
    }

    rt_kprintf("INA2262 Calibration: 0x%04X (%.1f)\n", cal_val, cal_val_float);
    rt_kprintf("2Current LSB: %d.%06d mA per bit\n", (int)current_lsb ,(int)(current_lsb-(int)current_lsb*1000));
    return RT_EOK;
}

/*读取瞬态电压 */
static float ina_read_shunt_voltage(rt_uint8_t ina226_addr)
{
    rt_uint16_t raw0;

    if (ina226_read_reg(ina226_addr,INA226_REG_SV, &raw0) == RT_EOK) {
            // 处理有符号值
            rt_int16_t signed_raw0 = (rt_int16_t)raw0;
            // 电流计算: Current = raw * current_lsb
            return signed_raw0 * 2.5f; // 转换为uV
        }
    return 0.0f;
}

/* 读取电流值 (mA) */
static float ina226_read_current(rt_uint8_t ina226_addr)
{
    rt_uint16_t raw;
//    rt_int16_t  current;

    if (ina226_read_reg(ina226_addr,INA226_REG_CURRENT, &raw) == RT_EOK) {
        // 处理有符号值
        rt_int16_t signed_raw = (rt_int16_t)raw;
        // 电流计算: Current = raw * current_lsb
        return signed_raw * current_lsb * 1000.000f; // 转换为mA
//        current = signed_raw * current_lsb * 1000.000f;
    }

    return 0.0f;
}
//计算平均电流---上班后继续写，将读取电流数据单独写入一个线程，定时去取数据，然后用平均数读取。
float calculateAverage(float values[],int size)
{
    float sum = 0 ;
    for (int i = 0;  i < size; ++ i) {
        sum += values[i];
    }
    return sum / size;
}
/* 读取电压值 (V) */
static float ina226_read_BUS(rt_uint8_t ina226_addr)
{
    rt_uint16_t raw2;

    if (ina226_read_reg(ina226_addr,INA226_REG_BUS, &raw2) == RT_EOK) {
        // 处理有符号值
        rt_int16_t signed_raw2 = (rt_int16_t)raw2;

        return signed_raw2 * Voltage_LSB *1.0f; // 转换为mV
    }
    return 0.0f;
}
/* 读取功率*/
static float ina226_read_power(rt_uint8_t ina226_addr)
{
    rt_uint16_t value;
    if (ina226_read_reg(ina226_addr,INA226_REG_PWR, &value) == RT_EOK)
    {
        rt_int16_t signed_raw3 = (rt_int16_t)value;
        return signed_raw3 * current_lsb *25.0f; // 转换为W
     }
    return 0.0f;
}
/*  */
static void ina226_read_all(rt_uint8_t ina226_addr)
{
    if (ina226_addr == INA226_ADDR1) {
        voltageVal = ina226_read_BUS(ina226_addr);
        Shunt_voltage = ina_read_shunt_voltage(ina226_addr);
        Shunt_Current = ina226_read_current(ina226_addr);
        Power = ina226_read_power(ina226_addr);
    } else if (ina226_addr == INA226_ADDR2)
    {
        voltageValB = ina226_read_BUS(ina226_addr);
        Shunt_voltageB = ina_read_shunt_voltage(ina226_addr);
        Shunt_CurrentB = ina226_read_current(ina226_addr);
        PowerB = ina226_read_power(ina226_addr);
    }

}
/* 线程入口函数 */
static void ina226_thread_entry(void *parameter)
{
    // 初始化INA226



    if (ina226_init() != RT_EOK) {
        return 1;
    }

    rt_thread_mdelay(10); // 等待初始化完成

    while (1) {

            ina226_read_all(INA226_ADDR1);
            ina226_read_all(INA226_ADDR2);
 //           rt_kprintf("uV_mA_V_W: %.03f,%.03f,%.03f,%.03f,%.03f,%.03f,%.03f,%.03f\n",Shunt_voltage,Shunt_Current,voltageVal/1000,Power,Shunt_voltageB,Shunt_CurrentB,voltageValB/1000,PowerB);
            rt_kprintf("uV_mA_V_W:%d.%0d,%d.%0d,%d.%0d,%d.%0d, ",(int)Shunt_voltage,(unsigned int)(Shunt_voltage*1000)%1000,(int)Shunt_Current,(unsigned int)(Shunt_Current*1000)%10000,(int)voltageVal/1000,(unsigned int)voltageVal%1000,(int)Power,(unsigned int)(Power*1000)%1000);
            rt_kprintf("%d.%0d,%d.%0d,%d.%0d,%d.%0d \n",(int)Shunt_voltageB,(unsigned int)(Shunt_voltageB*1000)%1000,(int)Shunt_CurrentB,(unsigned int)(Shunt_CurrentB*1000)%10000,(int)voltageValB/1000,(unsigned int)voltageValB%1000,(int)PowerB,(unsigned int)(PowerB*1000)%1000);
            rt_thread_mdelay(50); // 每50ms读取一次
    }
}
// //创建一个新线程专门用来做LCD显示电流电压
//static void LcdPlay_thread_entry(void *parameter)
//{
//
//    rt_uint8_t c1 = 0 ;
//    while(1)
//    {
//        enum key_event event = get_key_event(2);
//        if (event != KEY_EVENT_NONE)
//        {
//            if (event == KEY_EVENT_LONG_PRESS)
//            {
//                  c1 = 1 ;
//                  rt_kprintf("c1=%d\n",c1);
//             }
//            else {
//                c1 = 0 ;
//            }
//            if (c1 == 0) {
//                LCD_ShowString(3,3, 24*3, 24, 24, "C1", DARKBLUE, BLUE);
//            } else {
//                LCD_ShowString(3,3, 24*3, 24, 24, "C2", DARKBLUE, BRED);
//            }
//        }
//        if (c1 == 0) {
//            LCD_ShowFloatNum2(50,30,Shunt_Current,6,BLACK,WHITE,16);
//            LCD_ShowFloatNum1(50,55,voltageVal/1000,4,BLACK,WHITE,16);
//        } else {
//            LCD_ShowFloatNum2(50,30,Shunt_CurrentB,6,BLACK,WHITE,16);
//            LCD_ShowFloatNum1(50,55,voltageValB/1000,4,BLACK,WHITE,16);
//        }
//
//         rt_thread_mdelay(50);
//    }
//}
/* 创建处理线程 */
int INA226_INIT(void)
{
    rt_thread_t tid;
 //   rt_thread_t lcdplay;

    // 创建线程
    tid = rt_thread_create("ina226",
                           ina226_thread_entry,
                           RT_NULL,
                           1024,
                           RT_THREAD_PRIORITY_MAX / 2,
                           20);
    if (tid != RT_NULL) {
        rt_thread_startup(tid);
        rt_kprintf("INA226 thread startup\n");
    }
    else {
        rt_kprintf("INA226 thread start fail\n");
        return RT_ERROR;
    }

//    lcdplay = rt_thread_create("lcdplay",
//                           LcdPlay_thread_entry,
//                           RT_NULL,
//                           2048,
//                           RT_THREAD_PRIORITY_MAX -16,
//                           20);
//    if (lcdplay != RT_NULL) {
//        rt_thread_startup(lcdplay);
//        rt_kprintf("lcdplay thread startup\n");
//    }
//    else {
//        rt_kprintf("lcdplay thread start fail\n");
//        return RT_ERROR;
//    }

    return 0;
}
/* 初始化按键线程 */
//INIT_APP_EXPORT(INA226_INIT);
